package rmmk.zadanie2;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Random;
import java.util.logging.Logger;

import junit.framework.Assert;

import org.apache.commons.lang3.ArrayUtils;

public class TestAndAnalize {
	
	private Logger logger = Logger.getAnonymousLogger();
	
	private ISearch[] implementations;

	public TestAndAnalize(ISearch... impls)
	{
		this.implementations = impls; 
	}
	
	public void testAndAnalize(int startSize, int endSize, int step, double whichElement){
		
		startLogs(endSize, whichElement);
		
		for(int size = startSize; size < endSize; size+=step){
			int[] sortedArray = generateArray(size);
			
			int elementIndex = (int) (sortedArray.length * whichElement);
			int element = sortedArray[elementIndex];
			
			for(ISearch s : this.implementations){
				long shortestTime = Long.MAX_VALUE;
				int found = -1;
				
				for(int i = 0; i < 50; ++i){
					long startTime = System.nanoTime();
					
					found = s.find(element, sortedArray);
					
					long endTime = System.nanoTime();
					if(endTime - startTime < shortestTime)
						shortestTime = endTime - startTime;
						
				}
				log(s, size, shortestTime);
				
				Assert.assertEquals(elementIndex, found);
			}
			
			logger.info("Done: " + (((double) size / (double) endSize) * 100) +"% size: " + size);
		}
		endLogs();
		
		logger.info("Program ended");
	}
	
	private void endLogs() {
		for(Entry<ISearch, PlotWriter> e : writers.entrySet())
			e.getValue().end();
	}

	HashMap<ISearch, PlotWriter> writers = new HashMap<ISearch, PlotWriter>();
	private void startLogs(int endSize, double whichElement) {
		for(ISearch s : implementations)
		{
			writers.put(s, new PlotWriter(s, endSize, whichElement));
		}
	}

	private void log(ISearch s, int size, long shortestTime) {
		writers.get(s).log(size, shortestTime);	
	}

	private int[] generateArray(int size)
	{
		ArrayList<Integer> list = new ArrayList<Integer>(size);
		
		Random r = new Random();
		
		for(int i = 0; i < size; ++i)
			list.add(r.nextInt());
		
		Collections.sort(list);
		
		return  ArrayUtils.toPrimitive(list.toArray(new Integer[size]));
	}
}
